/*	=== 使用Fixture === 

在一个单元测试中，我们经常编写多个@Test方法，来分组、分类对目标代码进行测试。

在测试的时候，我们经常遇到一个对象需要初始化，测试完可能还需要清理的情况。如果每个@Test方法都写一遍这样的重复代码，显然比较麻烦。

JUnit提供了编写测试前准备、测试后清理的固定代码，我们称之为Fixture。

我们来看一个具体的Calculator的例子：	*/
public class Calculator {
	private long n = 0;

	public long add(long x) {
		n = n + x;
		return n;
	}

	public long sub(long x) {
		n = n - x;
		return n;
	}
}


/*
这个类的功能很简单

但是测试的时候，我们要先初始化对象

我们不必在每个测试方法中都写上初始化代码，而是通过@BeforeEach来初始化

通过@AfterEach来清理资源：	*/
public class CalculatorTest {
	Calculator calculator;

	@BeforeEach
	public void setUp() {
		this.calculator = new Calculator();
	}


	@Test
	void testAdd() {
		assertEquals(100, this.calculator.add(100));
		assertEquals(150, this.calculator.add(100));
		assertEquals(130, this.calculator.add(100));
	}

	@Test
	void testSub() {
		assertEquals(-100, this.calculator.sub(100));
		assertEquals(-150, this.calculator.sub(50));
		assertEquals(-130, this.calculator.sub(-20));
	}

	@AfterEach
	public void tearDown() {
		this.calculator = null;
	}
}


/*
在CalculatorTest测试中，有两个标记为@BeforeEach和@AfterEach的方法，它们会在运行每个@Test方法前后自动运行。

上面的测试代码在JUnit中运行顺序如下：	*/
for (Method testMethod : findTestMethods(CalculatorTest.class)) {
	var test = new CalculatorTest(); // 创建Test实例

	invokeBeforeEach(test);
	invokeTestMethod(test, testMethod);
	invokeAfterEach(test);
}


/*
可见，@BeforeEach和@AfterEach会“环绕”在每个@Test方法'前后'。

还有一些资源初始化和清理可能更加繁琐，而且会耗费较长的时间，例如初始化数据库。


----------------------------

JUnit还提供了@BeforeAll和@AfterAll，它们在运行所有@Test前后运行，顺序如下： */
invokeBeforeAll(CalculatorTest.class);

for (Method testMethod : findTestMethods(CalculatorTest.class)) {
	var test = new CalculatorTest(); // 创建Test实例

	invokeBeforeEach(test);
	invokeTestMethod(test, testMethod);
	invokeAfterEach(test);
}

invokeAfterAll(CalculatorTest.class);


// 因为@BeforeAll和@AfterAll在所有@Test方法运行前后仅运行一次，因此，它们只能初始化静态变量，例如：
public class DatabaseTest {
	static Database db;

	@BeforeAll
	public static void initDatabase() {
		db = createDb(...);
	}

	@AfterAll
	public static void dropDatabase() {
		//... 
	}
}


/*
事实上，@BeforeAll和@AfterAll也只能标注在静态方法上。


-------------------------

因此，我们总结出编写Fixture的套路如下：

	1.对于实例变量(Instance)，在@BeforeEach中初始化，在@AfterEach中清理，它们在各个@Test方法中互不影响，因为是不同的实例；

	2.对于静态变量(static Field)，在@BeforeAll中初始化，在@AfterAll中清理，它们在各个@Test方法中均是唯一实例，会影响各个@Test方法。

-----------------

大多数情况下，使用@BeforeEach和@AfterEach就足够了。

只有某些测试资源初始化耗费时间太长,以至于我们不得不尽量“复用”时才会用到@BeforeAll和@AfterAll。


最后，注意到每次运行一个@Test方法前，JUnit首先创建一个XxxTest实例，因此，每个@Test方法内部的成员变量都是独立的，不能也无法把成员变量的状态从一个@Test方法带到另一个@Test方法。


*/





/*	--- 使用Fixture の 小结 --- 

1.编写Fixture是指针对每个@Test方法，编写@BeforeEach方法用于初始化测试资源，编写@AfterEach用于清理测试资源；

2.必要时，可以编写@BeforeAll和@AfterAll，使用静态变量来初始化耗时的资源，并且在所有@Test方法的运行前后仅执行一次。


*/










































